<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Coze 文章生成器</title>
  <!-- Tailwind CSS v3 -->
  <script src="https://cdn.tailwindcss.com"></script>
  <!-- Font Awesome -->
  <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
  <!-- 统一的 Tailwind 配置 -->
  <script>
    tailwind.config = {
      theme: {
        extend: {
          colors: {
            primary: '#3B82F6',
            secondary: '#64748B',
            accent: '#10B981',
            neutral: '#F3F4F6',
            'neutral-dark': '#E5E7EB',
            danger: '#EF4444',
            warning: '#F59E0B',
            info: '#3B82F6',
            success: '#10B981'
          },
          fontFamily: {
            sans: ['Inter', 'system-ui', 'sans-serif'],
          },
          animation: {
            'pulse-slow': 'pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite',
          }
        }
      }
    }
  </script>
  <style type="text/tailwindcss">
    @layer utilities {
      .content-auto {
        content-visibility: auto;
      }
      .text-shadow {
        text-shadow: 0 2px 4px rgba(0,0,0,0.1);
      }
      .bg-gradient-blue {
        background: linear-gradient(135deg, #3B82F6 0%, #2563EB 100%);
      }
      .transition-all-300 {
        transition: all 300ms ease-in-out;
      }
    }
  </style>
</head>
<body class="bg-gray-50 text-gray-800 min-h-screen">
  <!-- 顶部导航栏 -->
  <header class="bg-white shadow-sm sticky top-0 z-10">
    <div class="container mx-auto px-4 py-4 flex justify-between items-center">
      <div class="flex items-center space-x-2">
        <div class="w-10 h-10 rounded-lg bg-gradient-blue flex items-center justify-center">
          <i class="fa fa-file-text-o text-white text-xl"></i>
        </div>
        <h1 class="text-xl font-bold text-gray-800">Coze 文章生成器</h1>
      </div>
      <div class="flex items-center space-x-4">
        <button id="theme-toggle" class="p-2 rounded-full hover:bg-gray-100 transition-all-300">
          <i class="fa fa-moon-o text-gray-600"></i>
        </button>
        <button id="help-button" class="p-2 rounded-full hover:bg-gray-100 transition-all-300">
          <i class="fa fa-question-circle-o text-gray-600"></i>
        </button>
      </div>
    </div>
  </header>

  <!-- 主要内容区域 -->
  <main class="container mx-auto px-4 py-8">
    <!-- 介绍卡片 -->
    <div class="bg-white rounded-xl shadow-sm p-6 mb-8">
      <h2 class="text-xl font-semibold mb-2">关于本工具</h2>
      <p class="text-gray-600 mb-4">
        本工具可以帮助您调用 Coze 工作流生成文章。只需输入您的 API Key 和文章主题，即可快速生成高质量的文章内容。
      </p>
      <div class="flex items-center text-sm text-gray-500">
        <i class="fa fa-info-circle mr-2"></i>
        <span>当前支持的工作流：文章生成</span>
      </div>
    </div>

    <!-- 输入区域 -->
    <div class="grid grid-cols-1 lg:grid-cols-3 gap-8 mb-8">
      <!-- API Key 输入 -->
      <div class="lg:col-span-1">
        <div class="bg-white rounded-xl shadow-sm p-6 h-full">
          <h3 class="text-lg font-medium font-semibold mb-4 flex">API 配置</h3>
          <div class="space-y-4">
            <div>
              <label for="api-key" class="block text-sm font-medium font-medium text-gray-700 mb-1">API Key</label>
              <div class="relative">
                <input type="password" id="api-key" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary transition-all-300" placeholder="sk-xxx..." value="pat_W7btxChA4uY5FUDUrUQItJprEB3oDsU5JHQK3NKqDmQpXnB4AdPzc1EXkttZ0A7b">
                <button id="toggle-api-key" class="absolute right-3 top-2.5 text-gray-500 hover:text-gray-700 transition-all-300">
                  <i class="fa fa-eye-slash"></i>
                </button>
              </div>
              <p class="mt-1 text-xs text-gray-500">您的 Coze API Key，可以在 Coze 平台的个人设置中找到。</p>
            </div>
            <div>
              <label for="workflow-id" class="block text-sm font-medium text-gray-700 mb-1">工作流 ID</label>
              <input type="text" id="workflow-id" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary transition-all-300" value="7566577660957950015" readonly>
              <p class="mt-1 text-xs text-gray-500">文章生成工作流的 ID，已预设为默认值。</p>
            </div>
            <div>
              <label for="space-id" class="block text-sm font-medium text-gray-700 mb-1">空间 ID</label>
              <input type="text" id="space-id" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary transition-all-300" value="7380640004466851877" readonly>
              <p class="mt-1 text-xs text-gray-500">工作流所在的空间 ID，已预设为默认值。</p>
            </div>
          </div>
        </div>
      </div>

      <!-- 参数输入 -->
      <div class="lg:col-span-2">
        <div class="bg-white rounded-xl shadow-sm p-6 h-full">
          <h3 class="text-lg font-semibold mb-4">文章参数</h3>
          <div class="space-y-4">
            <div>
              <label for="subject" class="block text-sm font-medium text-gray-700 mb-1">文章主题</label>
              <input type="text" id="subject" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary transition-all-300" placeholder="请输入文章主题，例如：人情世故的小故事">
              <p class="mt-1 text-xs text-gray-500">输入您想要生成的文章主题，工作流将基于此主题创作内容。</p>
            </div>
            <div>
              <label for="additional-params" class="block text-sm font-medium text-gray-700 mb-1">附加加上下文（可选）</label>
              <textarea id="additional-params" rows="4" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary transition-all-300" placeholder="可以添加一些额外的上下文或要求，例如：生成3个故事，每个故事包含一个生活场景和一个道理总结。"></textarea>
              <p class="mt-1 text-xs text-gray-500">可选的附加参数，用于更细致工作流生成更具体要求。</p>
            </div>
            <div class="pt-2">
              <button id="generate-button" class="w-full bg-primary hover:bg-blue-600 text-white font-medium py-2.5 px-4 rounded-lg transition-all-300 flex items-center justify-content-center">
                <i class="fa fa-magic mr-2"></i>
                <span>生成文章</span>
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 结果展示区域 -->
    <div id="result-container" class="bg-white rounded-xl shadow-sm p-6 mb-8 hidden">
      <div class="flex justify-between items-center mb-6">
        <h3 class="text-lg font-semibold">生成结果</h3>
        <div class="flex space-x-2">
          <button id="copy-button" class="inline-flex items-center px-3 py-1.5 border border-gray-300 rounded-lg text-sm font-medium text-gray-700 hover:bg-gray-50 transition-all-300">
            <i class="fa fa-copy mr-1.5"></i>
            <span>复制</span>
          </button>
          <button id="download-button" class="inline-flex items-center px-3 py-1.5 border border-gray-300 rounded-lg text-sm font-medium-medium text-gray-700 hover:bg-gray-50 transition-all-300">
            <i class="fa fa-download mr-1.5"></i>
            <span>下载</span>
          </button>
        </div>
      </div>
      
      <!-- 加载状态 -->
      <div id="loading-state" class="py-12 flex justify-center-center">
        <div class="animate-pulse flex flex-col items-center">
          <div class="w-12 h-12 border-4 border-primary border-t-transparent rounded-full animate-spin mb-4"></div>
          <p class="text-gray-600">正在生成文章，请稍候...</p>
          <p id="loading-progress" class="text-sm text-gray-500 mt-2">正在调用工作流...</p>
        </div>
      </div>
      
      <!-- 错误状态 -->
      <div id="error-state" class="py-12 flex flex-col-center hidden">
        <div class="flex flex-cols-1 items-center max-w-md">
          <div class="w-16 h-16 rounded-full-full bg-red-100 flex items-center justify-center mb-4">
            <i class="fa fa-exclamation-triangle text-red-500 text-2xl"></i>
          </div>
          <h4 class="text-lg font-medium text-gray-900 mb-2">生成失败</h4>
          <p id="error-message" class="text-gray-600 text-center">请求工作流时发生错误，请检查 API Key 是否正确并重试。</p>
          <button id="retry-button" class="mt-6 px-4 py-2 bg-primary hover:bg-blue-600 text-white font-medium rounded-lg transition-all-300">
            重试
          </button>
        </div>
      </div>
      
      <!-- 成功状态 -->
      <div id="success-state" class="hidden">
        <div id="article-content" class="prose max-w-none">
          <!-- 文章内容将在这里动态插入 -->
        </div>
        
        <!-- 图片生成区域 -->
        <div id="image-generation-section" class="mt-10">
          <h4 class="text-md font-semibold mb-4">图片生成</h4>
          <div id="image-prompts" class="space-y-6">
            <!-- 图片提示词和生成结果将在这里动态插入 -->
          </div>
        </div>
      </div>
    </div>

    <!-- 历史记录 -->
    <div id="history-section" class="bg-white rounded-xl shadow-sm p-6 mb-8 hidden">
      <h3 class="text-lg font-semibold mb-4">生成历史</h3>
      <div id="history-list" class="space-y-4">
        <!-- 历史记录将在这里动态插入 -->
      </div>
    </div>
  </main>

  <!-- 底部信息 -->
  <footer class="bg-white border-t border-gray-200 py-6">
    <div class="container mx-auto px-4">
      <div class="flex flex-col md:flex-row justify-between items-center">
        <p class="text-sm text-gray-500">© 2025 Coze 文章生成器 | 使用 Tailwind CSS 构建</p>
        <div class="flex space-x-4 mt-4 md:mt-0">
          <a href="#" class="text-sm text-gray-500 hover:text-primary transition-all-300">使用指南</a>
          <a href="#" class="text-sm text-gray-500 hover:text-primary transition-all-300">API 文档</a>
          <a href="#" class="text-sm text-gray-500 hover:text-primary transition-all-300">关于我们</a>
        </div>
      </div>
    </div>
  </footer>

  <!-- 帮助模态框 -->
  <div id="help-modal" class="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center items items-center hidden hidden">
    <div class="bg-white rounded-xl max-w-2xl w-full mx-4 max-h-[80vh] overflow-y-auto">
      <div class="p-6">
        <div class="flex justify-between items-center-center mb-4">
          <h3 class="text-xl font-semibold">使用帮助</h3>
          <button id="close-help" class="text-gray-500 hover:text-gray-700">
            <i class="fa fa-times text-xl"></i>
          </button>
        </div>
        <div class="space-y-4">
          <div>
            <h4 class="font-medium text-lg mb-2">如何获取 API Key？</h4>
            <p class="text-gray-600">
              1. 登录 Coze 平台<br>
              2. 进入个人设置页面<br>
              3. 在 API 密钥部分创建或复制您的 API Key
            </p>
          </div>
          <div>
            <h4 class="font-medium text-lg mb-2">如何使用本工具？</h4>
            <p class="text-gray-600">
              1. 输入您的 API Key<br>
              2. 填写文章主题和可选的附加参数<br>
              3. 点击"生成文章"按钮<br>
              4. 等待生成完成后查看结果
            </p>
          </div>
          <div>
            <h4 class="font-medium text-lg mb-2">关于工作流</h4>
            <p class="text-gray-600">
              本工具使用预设的 Coze 工作流来生成文章。工作流 ID 和空间 ID 已预设，无需修改。
            </p>
          </div>
          <div>
            <h4 class="font-medium text-lg mb-2">常见问题</h4>
            <div class="space-y-2">
              <p class="text-gray-600"><strong>Q: 生成文章需要多长时间？</strong><br>A: 通常情况下，生成一篇文章需要几到几十秒的时间，具体取决于文章长度和复杂度。</p>
              <p class="text-gray-600"><strong>Q: 生成的文章可以修改和下载吗？</strong><br>A: 是的，您可以复制生成的文章内容，也可以下载为 Markdown 文件。</p>
              <p class="text-gray-600"><strong>Q: 如何处理生成失败的情况？</strong><br>A: 请检查 API Key 是否正确，网络连接是否正常，或者尝试重试。</p>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>

  <!-- JavaScript -->
  <script>
    document.addEventListener('DOMContentLoaded', function() {
      // DOM 元素
      const apiKeyInput = document.getElementById('api-key');
      const toggleApiKeyBtn = document.getElementById('toggle-api-key');
      const workflowIdInput = document.getElementById('workflow-id');
      const spaceIdInput = document.getElementById('space-id');
      const subjectInput = document.getElementById('subject');
      const additionalParamsInput = document.getElementById('additional-params');
      const generateButton = document.getElementById('generate-button');
      const resultContainer = document.getElementById('result-container');
      const loadingState = document.getElementById('loading-state');
      const loadingProgress = document.getElementById('loading-progress');
      const errorState = document.getElementById('error-state');
      const errorMessage = document.getElementById('error-message');
      const successState = document.getElementById('success-state');
      const articleContent = document.getElementById('article-content');
      const imagePrompts = document.getElementById('image-prompts');
      const copyButton = document.getElementById('copy-button');
      const downloadButton = document.getElementById('download-button');
      const retryButton = document.getElementById('retry-button');
      const historySection = document.getElementById('history-section');
      const historyList = document.getElementById('history-list');
      const themeToggle = document.getElementById('theme-toggle');
      const helpButton = document.getElementById('help-button');
      const helpModal = document.getElementById('help-modal');
      const closeHelp = document.getElementById('close-help');

      // 切换 API Key 可见性
      toggleApiKeyBtn.addEventListener('click', function() {
        const type = apiKeyInput.getAttribute('type') === 'password' ? 'text' : 'password';
        apiKeyInput.setAttribute('type', type);
        toggleApiKeyBtn.innerHTML = type === 'password' ? '<i class="fa fa-eye-slash"></i>' : '<i class="fa fa-eye"></i>';
      });

      // 生成文章
      generateButton.addEventListener('click', generateArticle);
      retryButton.addEventListener('click', generateArticle);

      // 复制文章
      copyButton.addEventListener('click', function() {
        const text = articleContent.innerText;
        navigator.clipboard.writeText(text).then(() => {
          showToast('文章内容已复制到剪贴板');
        }).catch(err => {
          console.error('无法复制文本: ', err);
        });
      });

      // 下载文章
      downloadButton.addEventListener('click', function() {
        const text = articleContent.innerText;
        const blob = new Blob([text], { type: 'text/markdown' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = `article-${new Date().toISOString().slice(0, 10)}.md`;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
      });

      // 主题切换
      themeToggle.addEventListener('click', function() {
        document.body.classList.toggle('dark');
        const icon = themeToggle.querySelector('i');
        if (document.body.classList.contains('dark')) {
          icon.classList.remove('fa-moon-o');
          icon.classList.add('fa-sun-o');
        } else {
          icon.classList.remove('fa-sun-o');
          icon.classList.add('fa-moon-o');
        }
      });

      // 帮助模态框
      helpButton.addEventListener('click', function() {
        helpModal.classList.remove('hidden');
      });

      closeHelp.addEventListener('click', function() {
        helpModal.classList.add('hidden');
      });

      // 点击模态框外部关闭
      helpModal.addEventListener('click', function(e) {
        if (e.target === helpModal) {
          helpModal.classList.add('hidden');
        }
      });

      // 加载API配置缓存
      loadApiConfig();

      // 保存配置到缓存（包括API配置和文章参数）
      function saveApiConfig() {
        try {
          const config = {
            apiKey: apiKeyInput.value.trim(),
            workflowId: workflowIdInput.value.trim(),
            spaceId: spaceIdInput.value.trim(),
            subject: subjectInput.value.trim(),
            additionalParams: additionalParamsInput.value.trim()
          };
          localStorage.setItem('articleApiConfig', JSON.stringify(config));
        } catch (error) {
          console.error('保存配置失败:', error);
        }
      }

      // 加载配置缓存（包括API配置和文章参数）
      function loadApiConfig() {
        try {
          const savedConfig = localStorage.getItem('articleApiConfig');
          if (savedConfig) {
            const config = JSON.parse(savedConfig);
            if (config.apiKey) {
              apiKeyInput.value = config.apiKey;
            }
            if (config.workflowId) {
              workflowIdInput.value = config.workflowId;
            }
            if (config.spaceId) {
              spaceIdInput.value = config.spaceId;
            }
            if (config.subject) {
              subjectInput.value = config.subject;
            }
            if (config.additionalParams) {
              additionalParamsInput.value = config.additionalParams;
            }
          } else {
            // 如果没有保存的配置，使用默认的 API Key
            // 默认值已在 HTML input 的 value 属性中设置
          }
        } catch (error) {
          console.error('加载配置失败:', error);
        }
      }

      // 监听配置输入变化，自动保存
      apiKeyInput.addEventListener('input', function() {
        saveApiConfig();
      });

      workflowIdInput.addEventListener('input', function() {
        saveApiConfig();
      });

      spaceIdInput.addEventListener('input', function() {
        saveApiConfig();
      });

      // 监听文章参数输入变化，自动保存
      subjectInput.addEventListener('input', function() {
        saveApiConfig();
      });

      additionalParamsInput.addEventListener('input', function() {
        saveApiConfig();
      });

      // 加载历史记录
      loadHistory();

      // 生成文章函数
      function generateArticle() {
        const apiKey = apiKeyInput.value.trim();
        const workflowId = workflowIdInput.value.trim();
        const spaceId = spaceIdInput.value.trim();
        const subject = subjectInput.value.trim();

        // 验证输入
        if (!apiKey) {
          showToast('请输入 API Key', 'error');
          return;
        }

        if (!subject) {
          showToast('请输入文章主题', 'error');
          return;
        }

        // 显示结果容器和加载状态
        resultContainer.classList.remove('hidden');
        loadingState.classList.remove('hidden');
        errorState.classList.add('hidden');
        successState.classList.add('hidden');

        // 调用真实的 Coze 工作流 API
        callWorkflowApi(apiKey, workflowId, spaceId, subject, additionalParamsInput.value.trim())
          .then(response => {
            // 隐藏加载状态，显示成功状态
            loadingState.classList.add('hidden');
            successState.classList.remove('hidden');

            // 渲染文章内容
            renderArticle(response);

            // 保存到历史记录
            saveToHistory(subject, response);
          })
          .catch(error => {
            // 隐藏加载状态，显示错误状态
            loadingState.classList.add('hidden');
            errorState.classList.remove('hidden');
            errorMessage.textContent = error.message || '生成文章时发生错误，请重试。';
          });
      }

      // 调用 Coze 工作流 API（参考官方文档）
      async function callWorkflowApi(apiKey, workflowId, spaceId, subject, additionalParams) {
        // 更新加载进度
        loadingProgress.textContent = '正在调用工作流...';

        try {
          // 验证必要参数
          if (!apiKey || !apiKey.trim()) {
            throw new Error('API Key不能为空');
          }
          if (!workflowId || !workflowId.trim()) {
            throw new Error('工作流ID不能为空');
          }
          if (!spaceId || !spaceId.trim()) {
            throw new Error('空间ID不能为空');
          }

          // 构建用户输入消息
          let userContent = subject;
          if (additionalParams) {
            userContent = `${subject}\n\n附加要求：${additionalParams}`;
          }

          // 更新进度
          loadingProgress.textContent = '正在发送请求...';

          // 处理API Key：如果已包含Bearer前缀则去掉
          let authToken = apiKey.trim();
          if (authToken.startsWith('Bearer ') || authToken.startsWith('bearer ')) {
            authToken = authToken.substring(7).trim();
          }

          // 构建请求参数（按照Coze官方API文档格式）
          // 参考: https://api.coze.com/v1/workflows/run
          const apiRequestBody = {
            workflow_id: workflowId,
            app_id: spaceId, // 按需传入 app_id（来自页面的 spaceId 输入）
            parameters: {
              subject: userContent
            }
          };

          // 调试：输出请求信息（不输出完整API Key）
          console.log('API请求详情:', {
            endpoint: 'https://api.coze.com/v1/workflows/run',
            workflow_id: workflowId,
            apiKey_length: authToken.length,
            apiKey_prefix: authToken.substring(0, 10) + '...',
            apiKey_suffix: '...' + authToken.substring(authToken.length - 5),
            requestBody: apiRequestBody
          });

          // 调用 Coze API（使用官方文档中的端点）
          let response;
          try {
            response = await fetch('https://api.coze.com/v1/workflows/run', {
              method: 'POST',
              headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${authToken}`
              },
              body: JSON.stringify(apiRequestBody)
            });

            // 记录响应状态和头部信息
            console.log('API响应信息:', {
              status: response.status,
              statusText: response.statusText,
              contentType: response.headers.get('content-type'),
              url: response.url
            });
          } catch (fetchError) {
            console.error('请求发送失败:', fetchError);
            throw new Error(`网络请求失败: ${fetchError.message}`);
          }

          // 更新进度
          loadingProgress.textContent = '正在处理响应...';

          // 检查响应状态
          if (!response.ok) {
            // 先读取错误信息
            let errorText;
            try {
              errorText = await response.text();
            } catch (e) {
              errorText = '无法读取错误信息';
            }
            
            let errorData;
            try {
              errorData = JSON.parse(errorText);
            } catch (e) {
              errorData = { message: errorText || '请求失败' };
            }
            
            console.error('API错误响应:', {
              status: response.status,
              statusText: response.statusText,
              errorData: errorData,
              errorText: errorText
            });
            
            // 处理401错误，提供更详细的提示
            if (response.status === 401) {
              console.error('认证失败详情:', {
                status: response.status,
                errorData: errorData,
                apiKey_type: authToken.startsWith('pat_') ? 'PAT格式' : '非PAT格式',
                apiKey_length: authToken.length,
                apiKey_prefix: authToken.substring(0, 10),
                headers: {
                  'Content-Type': 'application/json',
                  'Authorization': `Bearer ${authToken.substring(0, 15)}...`
                }
              });
              
              const errorMsg = errorData.message || errorData.error?.message || errorData.error_msg || errorData.msg || '认证失败';
              let detailedError = `认证失败 (401): ${errorMsg}`;
              
              // 提供额外的诊断信息
              if (!authToken.startsWith('pat_')) {
                detailedError += '\n\n⚠️ 提示：API Key通常应以 "pat_" 开头。';
              }
              detailedError += '\n\n请检查：\n1. API Key是否正确且未过期\n2. API Key是否具有调用工作流的权限\n3. workflow_id 和 space_id 是否正确\n4. 是否在Coze开放平台正确配置了API访问';
              
              throw new Error(detailedError);
            }
            
            throw new Error(errorData.message || errorData.error?.message || errorData.msg || `HTTP错误: ${response.status} ${response.statusText}`);
          }

          // 检查响应类型
          const contentType = response.headers.get('content-type') || '';
          
          // 先读取响应内容进行检查
          let responseText = '';
          try {
            responseText = await response.text();
            
            // 检查是否是HTML错误页面
            const responseLower = responseText.trim().toLowerCase();
            if (responseLower.startsWith('<!doctype') || 
                responseLower.startsWith('<html') || 
                responseLower.includes('<!doctype')) {
              console.error('API返回了HTML页面（可能是错误页面）:', responseText.substring(0, 1000));
              
              // 尝试从HTML中提取错误信息
              let errorHint = '';
              if (responseText.includes('404') || responseText.includes('Not Found')) {
                errorHint = '端点不存在(404)，请检查API端点是否正确';
              } else if (responseText.includes('403') || responseText.includes('Forbidden')) {
                errorHint = '访问被禁止(403)，请检查API Key权限';
              } else if (responseText.includes('401') || responseText.includes('Unauthorized')) {
                errorHint = '认证失败(401)，请检查API Key是否正确';
              }
              
              throw new Error(`API端点返回了HTML页面，${errorHint}。\n\n请检查：\n1. API端点是否正确：https://api.coze.com/v1/workflows/run\n2. 是否需要在Coze平台配置API访问权限\n3. workflow_id 是否正确\n4. API Key是否有效且有权限`);
            }
          } catch (textError) {
            if (textError.message && textError.message.includes('API端点')) {
              throw textError;
            }
            console.error('读取响应文本失败:', textError);
            throw new Error(`无法读取API响应: ${textError.message}`);
          }
          
          let fullContent = '';

          // 如果是流式响应（SSE格式）
          if (contentType.includes('text/event-stream') || contentType.includes('text/plain')) {
            // 处理流式响应
            const reader = response.body.getReader();
            const decoder = new TextDecoder();
            let buffer = '';

            // 更新进度
            loadingProgress.textContent = '正在接收数据流...';

            while (true) {
              const { done, value } = await reader.read();
              
              if (done) {
                break;
              }

              // 解码数据块
              buffer += decoder.decode(value, { stream: true });
              
              // 处理SSE格式的数据
              const lines = buffer.split('\n');
              buffer = lines.pop() || ''; // 保留最后一个不完整的行

              for (const line of lines) {
                if (line.startsWith('data: ')) {
                  const dataStr = line.slice(6);
                  if (dataStr === '[DONE]') {
                    continue;
                  }
                  
                  try {
                    const data = JSON.parse(dataStr);
                    
                    // 提取内容
                    if (data.event === 'conversation.message.delta') {
                      if (data.delta && data.delta.content) {
                        fullContent += data.delta.content;
                        loadingProgress.textContent = '正在生成文章内容...';
                      }
                    } else if (data.event === 'conversation.message.completed') {
                      if (data.message && data.message.content) {
                        fullContent = data.message.content;
                        loadingProgress.textContent = '正在解析结果...';
                      }
                    } else if (data.content) {
                      fullContent += data.content;
                    }
                  } catch (e) {
                    // 如果不是JSON，直接添加
                    if (dataStr && dataStr !== '[DONE]') {
                      fullContent += dataStr;
                    }
                  }
                }
              }
            }
            // 流式响应处理完毕
          } else {
            // 如果不是流式响应，解析JSON响应
            // 使用已读取的responseText
            let data;
            try {
              // 解析已读取的响应文本
              data = JSON.parse(responseText);
            } catch (jsonError) {
              console.error('JSON解析失败，原始响应:', responseText.substring(0, 1000));
              
              // 如果已经检查过HTML，这里不应该再是HTML，但为了安全再检查一次
              const rawTextLower = responseText.trim().toLowerCase();
              if (rawTextLower.startsWith('<!doctype') || rawTextLower.startsWith('<html')) {
                throw new Error('API返回了HTML页面，可能是端点错误或需要认证。\n\n请检查：\n1. API端点是否正确\n2. API Key是否有权限\n3. workflow_id 和 space_id 是否正确\n4. 是否需要在Coze开放平台配置API访问权限');
              }
              
              // 如果看起来像错误信息，尝试提取
              if (responseText.includes('error') || responseText.includes('Error') || responseText.includes('401') || responseText.includes('403')) {
                throw new Error(`API返回错误: ${responseText.substring(0, 300)}`);
              }
              
              throw new Error(`无法解析API响应为JSON: ${jsonError.message}\n响应内容预览: ${responseText.substring(0, 300)}`);
            }
            
            // 尝试从不同路径提取内容
            if (data.message && data.message.content) {
              fullContent = data.message.content;
            } else if (data.content) {
              fullContent = data.content;
            } else if (data.output) {
              if (typeof data.output === 'string') {
                fullContent = data.output;
              } else if (data.output.text) {
                fullContent = data.output.text;
              } else if (data.output.content) {
                fullContent = data.output.content;
              } else {
                fullContent = JSON.stringify(data.output, null, 2);
              }
            } else if (data.data && data.data.content) {
              fullContent = data.data.content;
            } else {
              fullContent = JSON.stringify(data, null, 2);
            }
          }

          // 更新进度
          loadingProgress.textContent = '文章生成完成！';

          if (!fullContent) {
            throw new Error('未获取到有效的内容');
          }

          // 返回标准化的响应格式
          return {
            id: Date.now().toString(),
            type: 'text',
            content: fullContent
          };

        } catch (error) {
          console.error('调用工作流API失败:', error);
          
          // 提供更详细的错误信息
          let errorMessage = '调用工作流失败';
          if (error.message) {
            errorMessage = error.message;
          } else if (typeof error === 'string') {
            errorMessage = error;
          }
          
          throw new Error(errorMessage);
        }
      }

      // 渲染文章内容
      function renderArticle(response) {
        // 清空之前的内容
        articleContent.innerHTML = '';
        imagePrompts.innerHTML = '';

        // 解析文章内容
        const content = response.content;
        const sections = content.split(/\n(?=[一二三四五六七八九十]\s)/);

        sections.forEach(section => {
          if (!section.trim()) return;

          // 分割标题和内容
          const lines = section.split('\n');
          const title = lines[0].trim();
          const bodyLines = lines.slice(1).filter(line => line.trim() && !line.startsWith('插图文生图提示词：'));
          const imagePromptLine = lines.find(line => line.startsWith('插图文生图提示词：'));

          // 创建文章部分
          const articleSection = document.createElement('div');
          articleSection.className = 'mb-8 last:mb-0';

          // 添加标题
          const titleElement = document.createElement('h2');
          titleElement.className = 'text-xl font-semibold mb-4';
          titleElement.textContent = title;
          articleSection.appendChild(titleElement);

          // 添加内容
          const contentElement = document.createElement('div');
          contentElement.className = 'prose max-w-none';
          
          // 将内容行转换为段落
          const paragraphs = [];
          let currentParagraph = [];
          
          bodyLines.forEach(line => {
            if (line.startsWith('#')) {
              // 如果当前有未完成的段落，先添加
              if (currentParagraph.length > 0) {
                paragraphs.push(currentParagraph.join('\n'));
                currentParagraph = [];
              }
              // 添加标签行
              paragraphs.push(line);
            } else if (line.trim() === '') {
              // 如果是空行，结束当前段落
              if (currentParagraph.length > 0) {
                paragraphs.push(currentParagraph.join('\n'));
                currentParagraph = [];
              }
            } else {
              // 添加到当前段落
              currentParagraph.push(line);
            }
          });
          
          // 添加最后一个段落
          if (currentParagraph.length > 0) {
            paragraphs.push(currentParagraph.join('\n'));
          }
          
          // 渲染段落
          paragraphs.forEach(para => {
            if (para.startsWith('#')) {
              // 标签行
              const tagsElement = document.createElement('div');
              tagsElement.className = 'flex flex-wrap gap-2 mt-4';
              
              const tags = para.split('#').filter(tag => tag.trim());
              tags.forEach(tag => {
                const tagElement = document.createElement('span');
                tagElement.className = 'px-2 py-1 bg-blue-100 text-blue-800 text-xs font-medium rounded-full';
                tagElement.textContent = tag.trim();
                tagsElement.appendChild(tagElement);
              });
              
              contentElement.appendChild(tagsElement);
            } else {
              // 普通段落
              const pElement = document.createElement('p');
              pElement.className = 'mb-4';
              pElement.textContent = para;
              contentElement.appendChild(pElement);
            }
          });

          articleSection.appendChild(contentElement);
          articleContent.appendChild(articleSection);

          // 添加图片生成部分
          if (imagePromptLine) {
            const imagePrompt = imagePromptLine.replace('插图文生图提示词：', '').trim();
            
            const imageSection = document.createElement('div');
            imageSection.className = 'mt-6 p-4 border border-gray-200 rounded-lg';
            
            const promptElement = document.createElement('div');
            promptElement.className = 'mb-3';
            
            const promptLabel = document.createElement('p');
            promptLabel.className = 'text-sm font-medium text-gray-700 mb-1';
            promptLabel.textContent = '图片提示词：';
            promptElement.appendChild(promptLabel);
            
            const promptText = document.createElement('p');
            promptText.className = 'text-sm text-gray-600 italic';
            promptText.textContent = imagePrompt;
            promptElement.appendChild(promptText);
            
            const imageContainer = document.createElement('div');
            imageContainer.className = 'mt-4 aspect-video bg-gray-100 rounded-lg flex items-center justify-center relative overflow-hidden';
            
            const placeholder = document.createElement('div');
            placeholder.className = 'text-center';
            placeholder.innerHTML = `
              <i class="fa fa-image text-gray-400 text-3xl mb-2"></i>
              <p class="text-gray-500 text-sm">点击下方按钮生成图片</p>
            `;
            imageContainer.appendChild(placeholder);
            
            const generateImageButton = document.createElement('button');
            generateImageButton.className = 'mt-4 w-full bg-secondary hover:bg-gray-600 text-white text-sm font-medium py-2 px-4 rounded-lg transition-all-300';
            generateImageButton.innerHTML = '<i class="fa fa-camera mr-1.5"></i> 生成图片';
            generateImageButton.addEventListener('click', function() {
              generateImage(imagePrompt, imageContainer, generateImageButton);
            });
            
            imageSection.appendChild(promptElement);
            imageSection.appendChild(imageContainer);
            imageSection.appendChild(generateImageButton);
            
            const imagePromptItem = document.createElement('div');
            imagePromptItem.appendChild(imageSection);
            imagePrompts.appendChild(imagePromptItem);
          }
        });
      }

      // 生成图片
      function generateImage(prompt, container, button) {
        // 显示加载状态
        container.innerHTML = `
          <div class="animate-pulse flex flex-col items-center">
            <div class="w-12 h-12 border-4 border-primary border-t-transparent rounded-full animate-spin mb-4"></div>
            <p class="text-gray-600">正在生成图片，请稍候...</p>
          </div>
        `;
        
        // 禁用按钮
        button.disabled = true;
        button.innerHTML = '<i class="fa fa-spinner fa-spin mr-1.5"></i> 生成中...';
        
        // 模拟图片生成
        setTimeout(() => {
          // 创建图片元素
          const img = document.createElement('img');
          img.src = `https://picsum.photos/seed/${encodeURIComponent(prompt)}/800/450`;
          img.alt = prompt;
          img.className = 'w-full h-full object-cover transition-opacity duration-500';
          img.style.opacity = '0';
          
          // 图片加载完成后显示
          img.onload = function() {
            container.innerHTML = '';
            container.appendChild(img);
            setTimeout(() => {
              img.style.opacity = '1';
            }, 10);
            
            // 恢复按钮
            button.innerHTML = '<i class="fa fa-refresh mr-1.5"></i> 重新生成';
            button.disabled = false;
          };
          
          // 图片加载失败
          img.onerror = function() {
            container.innerHTML = `
              <div class="text-center">
                <i class="fa fa-exclamation-circle text-red-500 text-3xl mb-2"></i>
                <p class="text-red-500 text-sm">图片生成失败，请重试</p>
              </div>
            `;
            
            // 恢复按钮
            button.innerHTML = '<i class="fa fa-refresh mr-1.5"></i> 重试';
            button.disabled = false;
          };
        }, 3000);
      }

      // 保存到历史记录
      function saveToHistory(subject, response) {
        try {
          // 获取现有历史
          let history = JSON.parse(localStorage.getItem('articleHistory') || '[]');
          
          // 添加新记录
          const newRecord = {
            id: Date.now(),
            subject: subject,
            response: response,
            timestamp: new Date().toISOString()
          };
          
          // 限制历史记录数量
          history = [newRecord, ...history].slice(0, 10);
          
          // 保存到本地存储
          localStorage.setItem('articleHistory', JSON.stringify(history));
          
          // 更新历史记录显示
          loadHistory();
        } catch (error) {
          console.error('保存历史记录失败:', error);
        }
      }

      // 加载历史记录
      function loadHistory() {
        try {
          const history = JSON.parse(localStorage.getItem('articleHistory') || '[]');
          
          if (history.length === 0) {
            historySection.classList.add('hidden');
            return;
          }
          
          // 显示历史记录部分
          historySection.classList.remove('hidden');
          
          // 清空列表
          historyList.innerHTML = '';
          
          // 添加历史记录
          history.forEach(record => {
            const historyItem = document.createElement('div');
            historyItem.className = 'p-4 border border-gray-200 rounded-lg hover:bg-gray-50 transition-all-300 cursor-pointer';
            
            const header = document.createElement('div');
            header.className = 'flex justify-between items-center mb-2';
            
            const title = document.createElement('h4');
            title.className = 'font-medium text-gray-800 truncate';
            title.textContent = record.subject;
            
            const date = document.createElement('span');
            date.className = 'text-xs text-gray-500';
            date.textContent = formatDate(record.timestamp);
            
            header.appendChild(title);
            header.appendChild(date);
            
            historyItem.appendChild(header);
            
            // 添加点击事件
            historyItem.addEventListener('click', function() {
              // 显示结果容器和成功状态
              resultContainer.classList.remove('hidden');
              loadingState.classList.add('hidden');
              errorState.classList.add('hidden');
              successState.classList.remove('hidden');
              
              // 渲染文章内容
              renderArticle(record.response);
              
              // 滚动到结果区域
              resultContainer.scrollIntoView({ behavior: 'smooth' });
            });
            
            historyList.appendChild(historyItem);
          });
        } catch (error) {
          console.error('加载历史记录失败:', error);
          historySection.classList.add('hidden');
        }
      }

      // 格式化日期
      function formatDate(dateString) {
        const date = new Date(dateString);
        return `${date.getFullYear()}-${padZero(date.getMonth() + 1)}-${padZero(date.getDate())} ${padZero(date.getHours())}:${padZero(date.getMinutes())}`;
      }

      // 数字补零
      function padZero(num) {
        return num.toString().padStart(2, '0');
      }

      // 显示提示消息
      function showToast(message, type = 'success') {
        // 创建提示元素
        const toast = document.createElement('div');
        toast.className = `fixed top-4 right-4 px-4 py-2 rounded-lg shadow-lg z-50 transition-all duration-300 transform translate-x-full opacity-0 ${type === 'success' ? 'bg-green-500 text-white' : 'bg-red-500 text-white'}`;
        toast.textContent = message;
        
        // 添加到页面
        document.body.appendChild(toast);
        
        // 显示提示
        setTimeout(() => {
          toast.classList.remove('translate-x-full', 'opacity-0');
        }, 10);
        
        // 自动隐藏
        setTimeout(() => {
          toast.classList.add('translate-x-full', 'opacity-0');
          
          // 移除元素
          setTimeout(() => {
            document.body.removeChild(toast);
          }, 300);
        }, 3000);
      }
    });
  </script>
</body>
</html>
